package example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 【软件认证】日活月活统计
 *
 * 现有一份接口访问日志，记录于数组 logs 中，每个成员是一条日志，日志格式为：
 * yyyy-mm-dd|client_ip|url|result
 *
 * 各字段说明（竖线|分隔）：
 *
 * 字段yyyy-mm-dd：该条日志打印时间。注：约定每月固定为 31 天，从 1 开始计数；
 * 输入保证：这些日志都在同一个月内，但不保证日志是按日期有序的。
 *
 * 字段client_ip：为合法的点分十进制ipv4地址（1.1.1.1和1.01.001.1应视为同一个地址）；
 * 字段url：访问的地址，格式如 /login.do，/query.html，仅包含字母、.、/和_；
 * 字段result：接口访问结果，只有2种值：success 或 fail 。
 * 请根据日志记录统计该月的日活数和月活数，最后返回一个长度为 32 的整数序列，首个成员为月活数，后续依次为当月第 1~31 天的日活数。
 *
 * 统计规则：
 *
 * 日活数：统计当天合计有多少个不同的 client_ip 访问的地址是 /login.do，且结果为 success。
 * 月活数：统计当月合计有多少个不同的 client_ip 访问的地址是 /login.do，且结果为 success。
 * 输入
 * 参数为 logs，0 < logs.length <= 50000，logs[i] <= 150（即不超 150 个字符）
 *
 * 输出
 * 一个整数序列（32个成员），首个成员为月活数，后续依次为当月第 1~31 天的日活数。
 */

public class Exam003 {

    // 两种思路，一种是用一个完整的Array
    // 还有一个是用一个Map


    int[] getActiveUserNum(List<String> logs) {

        int[] dayCount = new int[32];
        Map<Integer, Set<String>> everyDayLive = new HashMap<>();
        Set<String> monthLiveSet = new HashSet<>();
        for (String log : logs) {
            String[] logArray = log.split("\\|");
            String day = logArray[0];

            String[] dayArray = day.split("-");

            String dayString = dayArray[2];

            int dayIndex = Integer.parseInt(dayString);

            if (logArray[2].equals("/login.do") && logArray[3].equals("success")) {
                String realIpAddress = removeLeadingZeros(logArray[1]);
                if (everyDayLive.get(dayIndex) == null) {
                    Set<String> ipList = new HashSet<>();
                    ipList.add(realIpAddress);
                    everyDayLive.put(dayIndex, ipList);
                } else {
                    Set<String> liveIpList = everyDayLive.get(dayIndex);
                    liveIpList.add(realIpAddress);
                }
                monthLiveSet.add(realIpAddress);
            }
        }

        dayCount[0] = monthLiveSet.size();

        for (int i = 1; i < 32; i++) {
            Set<String> ervryDaySet = everyDayLive.getOrDefault(i, new HashSet<>());
            dayCount[i] = ervryDaySet.size();
        }

        return dayCount;
    }

    /**
     * 去除IP地址中各段的前导0
     * @param ip 原始IP地址
     * @return 格式化后的IP地址
     */
    public static String removeLeadingZeros(String ip) {
        // 按照点号分割IP地址
        String[] parts = ip.split("\\.");
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < parts.length; i++) {
            // 将每段转换为整数，自动去除前导0
            int num = Integer.parseInt(parts[i]);
            result.append(num);

            // 除了最后一段，其他段后添加点号
            if (i < parts.length - 1) {
                result.append(".");
            }
        }

        return result.toString();
    }

    public static void main(String[] args) {
        Exam003 exam003 = new Exam003();
        List<String> stringList = new ArrayList<>();

        stringList.add("2020-02-01|192.168.218.218|/login.do|success");
        stringList.add("2020-02-01|192.168.218.218|/login.do|success");
        stringList.add("2020-02-01|192.168.210.210|/login.do|fail");
        stringList.add("2020-02-02|192.168.210.210|/login.do|success");
        stringList.add("2020-02-02|192.168.218.218|/login.do|success");
        int[] activeUserNum = exam003.getActiveUserNum(stringList);
        System.out.printf(Arrays.toString(activeUserNum));


    }
}
